#include "napi/native_api.h"
#include <arkui/native_node_napi.h>
#include <arkui/native_node.h>
#include <arkui/native_type.h>
#include <arkui/native_interface.h>
#include <cstdint>
#include <multimedia/image_framework/image/image_source_native.h>
#include <multimedia/image_framework/image/pixelmap_native.h>

#include <js_native_api.h>
#include "hilog/log.h"
#include "rlottie.h"

#include "NativeEntry.h"

#include "ArkUICustomContainerNode.h"
#include "ArkUICustomNode.h"

#include <arkui/native_node_napi.h>
#include <arkui/native_type.h>
#include <js_native_api.h>
#include "Animate.h"
#include "ImageNode.h"
#include "Xcom.h"

Animate *LalAnimate;
static napi_value stopPlay(napi_env env, napi_callback_info info)
{

    LalAnimate->Stop();
    return nullptr;
}

static napi_value Add(napi_env env, napi_callback_info info)
{
    size_t argc = 2;
    napi_value args[2] = {nullptr};

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    std::string FileName = "/data/storage/el2/base/haps/entry/files/Unititled.json";
    std::chrono::nanoseconds startTime;
    std::chrono::nanoseconds endTime;
    auto now = std::chrono::high_resolution_clock::now();
    startTime = std::chrono::time_point_cast<std::chrono::nanoseconds>(now).time_since_epoch();
    // 设定 rlottie缓冲区为0
//     lottie_configure_model_cache_size(0);
    auto player = rlottie::Animation::loadFromFile(FileName);

    now = std::chrono::high_resolution_clock::now();
    endTime = std::chrono::time_point_cast<std::chrono::nanoseconds>(now).time_since_epoch();
    DRAWING_LOGE("\n\n\n间隔时间%{public}ld时间戳", endTime - startTime);

    napi_value sum;
    napi_create_double(env, 4, &sum);

    return sum;
}

namespace NativeModule {
napi_value CreateNativeRoot(napi_env env, napi_callback_info info)
{
    size_t argc = 1;
    napi_value args[1] = {nullptr};

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    void *temp = nullptr;
    napi_unwrap(env, args[0], &temp);

    // 获取NodeContent
    ArkUI_NodeContentHandle contentHandle;
    OH_ArkUI_GetNodeContentFromNapiValue(env, args[0], &contentHandle);
    NativeEntry::GetInstance()->SetContentHandle(contentHandle);

    // 创建自定义容器和自定义绘制组件。
    auto node = std::make_shared<ArkUICustomContainerNode>();
    ArkUI_ContextHandle LalHandle = nullptr;
    LalHandle = OH_ArkUI_GetContextByNode(node->GetHandle());
    LalAnimate = new Animate(LalHandle);

    // 如果选择DrawingC 就是 1
    if (1) {
        auto customNode = std::make_shared<ArkUICustomNode>(200,200);
        // 设置自定义组件宽高
        node->AddChild(customNode);
        LalAnimate->SetNode(customNode);
    } else if (0) {
        auto imageNode = std::make_shared<ImageNode>(100, 100);
        node->AddChild(imageNode);
        LalAnimate->SetNode(imageNode);
    } else if (0) {
        auto XcomponentNode =
            std::make_shared<XcomNode>(200, 200, "/data/storage/el2/base/haps/entry/files/Unititled.json");
        node->AddChild(XcomponentNode);
    }

    // 保持Native侧对象到管理类中，维护生命周期。
    NativeEntry::GetInstance()->SetRootNode(node);

    LalAnimate->Play();

    struct napi_env__ *g_env = env;
    return nullptr;
}

napi_value DestroyNativeRoot(napi_env env, napi_callback_info info)
{
    // 从管理类中释放Native侧对象。
    NativeEntry::GetInstance()->DisposeRootNode();
    return nullptr;
}
} // namespace NativeModule

EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
    napi_property_descriptor desc[] = {
        {"add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"stopPlay", nullptr, stopPlay, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"createNativeRoot", nullptr, NativeModule::CreateNativeRoot, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"destroyNativeRoot", nullptr, NativeModule::DestroyNativeRoot, nullptr, nullptr, nullptr, napi_default,
         nullptr},
    };
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}
EXTERN_C_END

static napi_module demoModule = {
    .nm_version = 1,
    .nm_flags = 0,
    .nm_filename = nullptr,
    .nm_register_func = Init,
    .nm_modname = "entry",
    .nm_priv = ((void *)0),
    .reserved = {0},
};

extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
{
    napi_module_register(&demoModule);
}
